Skip to content

feat: support bare repositories with worktrees #4783

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

sQVe
Copy link

@sQVe sQVe commented Jul 29, 2025

Summary

Enables lazygit to work with bare Git repositories that use worktrees, fixing crashes when running lazygit from directories containing bare repo + worktree setups. This resolves the "fatal: this operation must be run in a work tree" error that prevents lazygit from starting in these advanced Git workflow scenarios.

Problem solved: Previously, running lazygit in a directory like:

/project/
├── .bare/          # bare repository
├── main/           # worktree for main branch
└── .git            # points to .bare

Would crash with: fatal: this operation must be run in a work tree

Solution: lazygit now detects the bare repo setup and automatically opens in the appropriate worktree (e.g., main branch).

Changes

  • Bare repository detection: Added detection logic for common bare repo patterns (.bare, bare.git, .git)
  • Worktree selection: Implemented algorithm to automatically select the best worktree, prioritizing default branch, then main/master, then alphabetical order
  • Comprehensive test coverage: Added 218 lines of tests covering various bare repo + worktree scenarios including edge cases

Test Plan

For reviewers to verify:

  • Test with standard non-bare repositories (existing functionality unchanged)
  • Test bare repository with single worktree (should work automatically)
  • Test bare repository with multiple worktrees (should select main/master branch worktree)
  • Test bare repository with custom default branch (should select correctly)
  • Test error handling for invalid/missing bare repositories
  • Run existing test suite to ensure no regressions: go test ./pkg/commands/git_commands/
  • Test path traversal protection with malicious directory inputs

Enables lazygit to work with bare Git repositories that use worktrees, improving compatibility with advanced Git workflows.
@stefanhaller
Copy link
Collaborator

Sorry for the delay in looking at this.

I'm not experienced with either bare repos or worktrees (even in non-bare repos), so maybe these are stupid questions, but I don't understand why you can't simply cd into your worktree and run lazygit there. In my brief testing, this worked fine with a worktree that is attached to a bare repo. But I also don't understand what /project/.git is in your picture above, so maybe your setup is somehow different from what I thought is the usual one. Can you explain?

@sQVe
Copy link
Author

sQVe commented Aug 13, 2025

Sorry for the delay in looking at this.

No problem at all. I've been real busy also 😉

Can you explain?

Yes, of course!

There is a worktree structure that is considered best practice, and most common. This pattern is recommended because it:

  • Keeps all worktrees organized under a single project directory
  • Maintains a single source of truth for all branches and history
  • Allows for executing git commands from project/ directory.

You structure your project like this:

project/
 ├── .bare/          # The bare repository
 ├── feat-example/   # Worktree for feat-example branch
 ├── hotfix/         # Worktree for quick hotfixes
 ├── main/           # Worktree for main branch
 └── .git            # Optional: Git file with `gitdir: .bare` that makes regular git commands work from project root

This allows you to get a great overview of your worktrees, while keeping your version history at one place. You are essentially creating a pool of worktrees that you can move in and out of.

Current behavior (crashes):

cd /project
lazygit
# Error: fatal: this operation must be run in a work tree

Expected behavior (with this PR):

cd /project
lazygit
# Automatically detects bare repo setup and opens in main worktree

Why not just "cd into the worktree"?

You're absolutely right that users can cd into the worktree and run lazygit there. However:

  1. Project-level operations: My git information is housed within the .bare/ directory, which resides in the root of the project/ directory. As a user I would expect to be able to open lazygit from the project/ root.
  2. Awkward workflow: I find it very awkward to cd into one worktree to do things like:
    • Removing another worktree
    • Viewing the overall worktree status
    • Managing branches across all worktrees
    • These are project-level operations, not worktree-specific ones
  3. Workflow consistency: Other Git tools (like git itself) work from the project root when there's a .git file pointing to the bare repo. For example, git worktree list works from /project/.

I hope that clarifies why I created this PR. 🙏🏼

@stefanhaller
Copy link
Collaborator

Thanks for the explanation, makes a lot of sense. The setup sounds very useful, and I'm probably going to switch to that setup for my work repos.

However, I'm not convinced yet that being able to open lazygit from project/ is a good idea. This would make it seem like you can open the bare repo itself with lazygit, and work with it like you can with git CLI. This could be confusing; for example, if you cd into project/ and launch lazygit in order to create a new worktree, you might think that you should use a path like my-new-wt to create it under project/. However, you need to use ../my-new-wt, and that's very non-obvious I think. Having to explicitly cd into one of your worktrees and launch lazygit there makes this much clearer for me.

I feel that we shouldn't weaken the requirement that lazygit needs a worktree in order to work. Only work trees show up in the recent repos list; the project/ directory doesn't.

I'm still new to this workflow, so maybe I'm missing things here. Will play with this some more to get a better feeling for it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants